from rest_framework import viewsets, permissions, status, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from django.utils import timezone
from django_filters.rest_framework import DjangoFilterBackend
from .models import Order, OrderItem
from .serializers import OrderSerializer, OrderItemSerializer
from users.permissions import PurchaserPermission, SalesmanPermission, DeliverymanPermission, CustomerPermission, IsAdmin
from django.db.models import Sum, F
from django.db.models.functions import TruncDay, TruncMonth
from django.db.models import Count
import random
from delivery.models import DeliverymanArea, DeliveryStatusRecord
from django.db import transaction
from django.shortcuts import get_object_or_404

# 将函数移到模块级别
def auto_assign_deliveryman_helper(delivery_task, operator):
    """自动分配配送员的辅助函数，可以在任何地方调用"""
    try:
        from users.models import User
        from delivery.models import DeliveryArea, DeliverymanArea, DeliveryStatusRecord
        import random
        
        # 获取订单地址
        order_address = delivery_task.sales_order.address
        if not order_address:
            return False
        
        # 从地址中提取区域信息（假设地址格式为：省份 城市 区域 详细地址）
        address_parts = order_address.split()
        if len(address_parts) < 3:
            return False
            
        # 提取区域名称
        province = address_parts[0] if len(address_parts) > 0 else ""
        city = address_parts[1] if len(address_parts) > 1 else ""
        district = address_parts[2] if len(address_parts) > 2 else ""
        
        # 构建可能的区域名称格式
        possible_area_names = [
            f"{city}{district}",
            f"{province}{district}",
            district,
            city
        ]
        
        # 查找匹配的配送区域
        matching_areas = DeliveryArea.objects.filter(
            name__in=possible_area_names, 
            status='active'
        )
        
        if not matching_areas.exists():
            # 如果找不到精确匹配，尝试模糊匹配
            for area_name in possible_area_names:
                areas = DeliveryArea.objects.filter(
                    name__contains=area_name,
                    status='active'
                )
                if areas.exists():
                    matching_areas = areas
                    break
            
            if not matching_areas.exists():
                return False
        
        # 获取区域内的配送员
        deliveryman_areas = DeliverymanArea.objects.filter(area__in=matching_areas)
        deliverymen_ids = deliveryman_areas.values_list('deliveryman_id', flat=True).distinct()
        deliverymen = User.objects.filter(id__in=deliverymen_ids, is_active=True)
        
        if not deliverymen.exists():
            return False
            
        # 计算每个配送员在该区域的活跃度
        from django.db.models import Count, Q
        active_tasks = Q(delivery_tasks__status='completed') | Q(delivery_tasks__status='delivering')
        deliverymen = deliverymen.annotate(
            area_task_count=Count(
                'delivery_tasks',
                filter=active_tasks & Q(delivery_tasks__sales_order__address__contains=district)
            )
        )
        
        # 按区域任务数量降序排序
        deliverymen = deliverymen.order_by('-area_task_count')
        
        # 处理被拒绝的配送员逻辑
        rejected_deliveryman_id = None
        if delivery_task.status_records.filter(status='pending').exists():
            last_record = delivery_task.status_records.filter(status='pending').order_by('-created_at').first()
            if last_record and '配送员' in last_record.note:
                import re
                match = re.search(r'配送员 (.*?) 拒绝任务', last_record.note)
                if match:
                    rejected_deliveryman_name = match.group(1)
                    rejected_user = User.objects.filter(username=rejected_deliveryman_name).first()
                    if rejected_user:
                        rejected_deliveryman_id = rejected_user.id
        
        # 选择合适的配送员
        selected_deliveryman = None
        
        if deliverymen.exists():
            max_activity = deliverymen.first().area_task_count
            most_active_deliverymen = list(deliverymen.filter(area_task_count=max_activity))
            
            if rejected_deliveryman_id:
                most_active_deliverymen = [d for d in most_active_deliverymen if d.id != rejected_deliveryman_id]
                if not most_active_deliverymen:
                    second_max = deliverymen.exclude(area_task_count=max_activity).order_by('-area_task_count').first()
                    if second_max:
                        second_max_value = second_max.area_task_count
                        most_active_deliverymen = list(deliverymen.filter(area_task_count=second_max_value))
            
        if most_active_deliverymen:
            selected_deliveryman = random.choice(most_active_deliverymen)
        
        if selected_deliveryman:
            # 更新配送任务
            delivery_task.deliveryman = selected_deliveryman
            delivery_task.status = 'assigned'
            delivery_task.save()
            
            # 创建状态记录
            DeliveryStatusRecord.objects.create(
                delivery_task=delivery_task,
                status='assigned',
                operator=operator,
                note=f"系统自动分配任务给配送员: {selected_deliveryman.username}，区域: {matching_areas.first().name}"
            )
            
            return True
        return False
    except Exception as e:
        print(f"自动分配配送员时出错: {str(e)}")
        return False

class OrderViewSet(viewsets.ModelViewSet):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['status', 'order_number']
    search_fields = ['order_number', 'customer__username']
    ordering_fields = ['created_at', 'total_amount']
    ordering = ['-created_at']

    def get_permissions(self):
        if self.action in ['create']:
            # 允许任何已认证用户创建订单
            return [permissions.IsAuthenticated()]
        elif self.action in ['update', 'partial_update', 'destroy']:
            # 使用自定义组合权限类
            class CombinedPermission(permissions.BasePermission):
                def has_permission(self, request, view):
                    return (SalesmanPermission().has_permission(request, view) or
                            PurchaserPermission().has_permission(request, view) or
                            IsAdmin().has_permission(request, view))
            return [CombinedPermission()]
        return [permissions.IsAuthenticated()]

    def get_queryset(self):
        user = self.request.user
        queryset = Order.objects.all()
        
        # 过滤条件
        order_number = self.request.query_params.get('order_number')
        status = self.request.query_params.get('status')
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')
        
        if order_number:
            queryset = queryset.filter(order_number__icontains=order_number)
        if status:
            queryset = queryset.filter(status=status)
        if start_date:
            queryset = queryset.filter(created_at__gte=start_date)
        if end_date:
            queryset = queryset.filter(created_at__lte=end_date)
        
        # 根据用户角色过滤
        if user.role == 'admin':
            return queryset
        elif user.role == 'purchaser':
            return queryset.filter(customer=user)
        elif user.role == 'salesman':
            return queryset
        elif user.role == 'customer':
            return queryset.filter(customer=user)
        elif user.role == 'deliveryman':
            return queryset.filter(status__in=['paid', 'shipped'])
        return Order.objects.none()

    def create(self, request, *args, **kwargs):
        # 添加客户信息
        request.data['customer'] = request.user.id
        request.data['items_data'] = request.data.pop('items', [])
        
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        
        return Response({
            'code': 200,
            'message': '创建成功',
            'data': {
                'order_number': serializer.instance.order_number,
                'total_amount': serializer.instance.total_amount
            }
        })

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        # 只允许删除已取消的订单
        if instance.status != 'cancelled':
            return Response({
                'code': 400,
                'message': '只能删除已取消的订单'
            }, status=status.HTTP_400_BAD_REQUEST)
            
        try:
            # 先删除关联的订单项
            instance.items.all().delete()
            # 删除订单
            self.perform_destroy(instance)
            return Response({
                'code': 200,
                'message': '删除成功'
            }, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'删除失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response({
                'code': 200,
                'message': '获取成功',
                'data': {
                    'total': self.paginator.page.paginator.count,
                    'items': serializer.data
                }
            })
        
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            'code': 200,
            'message': '获取成功',
            'data': {
                'total': queryset.count(),
                'items': serializer.data
            }
        })

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({
            'code': 200,
            'message': '获取成功',
            'data': serializer.data
        })

    @action(detail=True, methods=['put'])
    def status(self, request, pk=None):
        """更新订单状态"""
        order = self.get_object()
        new_status = request.data.get('status')
        payment_method = request.data.get('payment_method')
        note = request.data.get('note')
        
        if new_status not in dict(Order.STATUS_CHOICES):
            return Response({
                'code': 400,
                'message': '无效的状态'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 如果订单状态变为已取消，检查是否可以取消
        if new_status == 'cancelled':
            # 只有订单已付款但未发货的时候才能取消
            if order.status not in ['paid']:
                return Response({
                    'code': 400,
                    'message': '只有已付款但未发货的订单可以取消'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 如果存在配送任务，将其状态更新为已取消
            try:
                from delivery.models import DeliveryTask
                if hasattr(order, 'delivery_task'):
                    delivery_task = order.delivery_task
                    delivery_task.status = 'cancelled'
                    delivery_task.save()
                    
                    # 创建配送状态记录
                    from delivery.models import DeliveryStatusRecord
                    DeliveryStatusRecord.objects.create(
                        delivery_task=delivery_task,
                        status='cancelled',
                        operator=request.user,
                        note=f"订单 {order.order_number} 已取消，配送任务自动取消"
                    )
            except Exception as e:
                # 记录错误但不影响订单状态更新
                print(f"取消配送任务时出错: {str(e)}")
        
        # 更新订单状态
        order.status = new_status
        
        # 如果状态是已付款，自动创建配送任务
        if new_status == 'paid' and payment_method:
            order.payment_method = payment_method
            order.payment_time = timezone.now()
            
            # 如果状态是已付款，自动创建配送任务
            try:
                # 检查是否已存在配送任务
                from delivery.models import DeliveryTask
                if not hasattr(order, 'delivery_task'):
                    # 生成配送编号
                    import uuid
                    delivery_number = f'DT{timezone.now().strftime("%Y%m%d")}{str(uuid.uuid4().int)[:6]}'
                    
                    # 创建配送任务
                    delivery_task = DeliveryTask.objects.create(
                        delivery_number=delivery_number,
                        sales_order=order,
                        status='pending',
                        priority='medium',
                        estimated_delivery_time=timezone.now() + timezone.timedelta(days=3),
                        note=f'订单 {order.order_number} 的配送任务'
                    )
                    
                    # 自动分配配送员 - 使用模块级别的辅助函数
                    self.auto_assign_deliveryman(delivery_task, request.user)
            except Exception as e:
                # 记录错误但不影响订单状态更新
                print(f"创建配送任务时出错: {str(e)}")
        
        # 如果有备注，更新备注
        if note:
            order.remark = note if not order.remark else f"{order.remark}\n{note}"
        
        order.save()
        
        return Response({
            'code': 200,
            'message': '更新成功'
        })

    @action(detail=False, methods=['get'], url_path='sales-report')
    def sales_report(self, request):
        """生成销售分析报告，支持本周、本月"""
        period = request.query_params.get('period', 'week')  # week or month
        if period == 'month':
            trunc_func = TruncMonth
        else:
            trunc_func = TruncDay
        
        # 只统计已完成订单
        order_items = OrderItem.objects.filter(order__status__in=['paid', 'shipped', 'completed'])
        sales_data = order_items.annotate(period=trunc_func('order__created_at')) \
            .values('product__name', 'period') \
            .annotate(total_quantity=Sum('quantity'), total_amount=Sum('total_price')) \
            .order_by('product__name', 'period')
        
        return Response({
            'code': 200,
            'message': '获取成功',
            'data': list(sales_data)
        })

    def auto_assign_deliveryman(self, delivery_task, operator):
        """自动分配配送员"""
        return auto_assign_deliveryman_helper(delivery_task, operator)

class OrderItemViewSet(viewsets.ModelViewSet):
    queryset = OrderItem.objects.all()
    serializer_class = OrderItemSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_permissions(self):
        if self.action in ['create', 'update', 'partial_update', 'destroy']:
            return [SalesmanPermission()|PurchaserPermission()|IsAdmin()]
        return [permissions.IsAuthenticated()]

    def get_queryset(self):
        user = self.request.user
        if user.role == 'admin':
            return OrderItem.objects.all()
        elif user.role == 'salesman':
            return OrderItem.objects.all()
        elif user.role == 'purchaser':
            return OrderItem.objects.all()
        elif user.role == 'customer':
            return OrderItem.objects.filter(order__customer=user)
        elif user.role == 'deliveryman':
            return OrderItem.objects.filter(order__delivery__deliveryman=user)
        return OrderItem.objects.none()

    def auto_assign_deliveryman(self, delivery_task, operator):
        """自动分配配送员"""
        return auto_assign_deliveryman_helper(delivery_task, operator)